//
//  DBBaseWebViewController.swift
//  DBCA
//
//  Created by mugua on 2024/7/6.
//

import Foundation
import WebKit
import StoreKit

let DBSereneMeadow = "sereneMeadow"
let DBSwilightHour = "twilightHour"
let DBUrbanVibes   = "urbanVibes"
let DBVelvetNight  = "velvetNight"
let DBWhisperWind  = "whisperWind"
let DBAzureHorizon = "azureHorizon"

class DBBaseWebViewController: DBBaseViewController, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate {
    
    var webView: WKWebView?
    let disposeBag = DisposeBag()
    let progressView = UIProgressView(progressViewStyle: .default)
    var lastProgress: Float = 0.0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        initWKWebView()
    }
    
    deinit {
        self.webView?.stopLoading()
        self.webView?.navigationDelegate = self
        self.webView?.removeFromSuperview()
    }
    
    var url: String? {
        didSet {
            
            guard let url = url, let URL = URL(string: url) else { return }
            let request = URLRequest(url: URL)
            self.webView?.load(request)
        }
    }
    
    func initWKWebView() {
        let configuration = WKWebViewConfiguration()
        let preferences = WKPreferences()
        preferences.javaScriptCanOpenWindowsAutomatically = true
        configuration.preferences = preferences
        configuration.preferences.javaScriptEnabled = true
        configuration.allowsInlineMediaPlayback = true
      
        configuration.userContentController.add(self, name: DBSereneMeadow)
        configuration.userContentController.add(self, name: DBSwilightHour)
        configuration.userContentController.add(self, name: DBUrbanVibes)
        configuration.userContentController.add(self, name: DBVelvetNight)
        configuration.userContentController.add(self, name: DBWhisperWind)
        configuration.userContentController.add(self, name: DBAzureHorizon)
        
        self.webView = WKWebView(frame: CGRectZero, configuration: configuration)
        view.addSubview(self.webView!)
        self.webView?.snp.makeConstraints({ make in
            make.edges.equalToSuperview()
        })
        
        self.webView?.backgroundColor = .white
        self.webView?.allowsBackForwardNavigationGestures = true
        self.webView?.translatesAutoresizingMaskIntoConstraints = false
        self.webView?.uiDelegate = self
        self.webView?.navigationDelegate = self
        self.webView?.scrollView.decelerationRate = .normal
//        self.webView?.addObserver(self, forKeyPath: "estimatedProgress", context: nil)
        
        webView?.rx.observe(Float.self, "estimatedProgress")
            .compactMap { $0 }
            .observe(on: MainScheduler.instance)
                    .subscribe(onNext: { [weak self] progress in
                        self?.updateProgress(progress: progress)
                    })
                    .disposed(by: disposeBag)
        if #available(iOS 11.0, *) {
            self.webView?.scrollView.contentInsetAdjustmentBehavior = .never
        }
        
        guard let url = url, let URL = URL(string: url) else { return }
        let request = URLRequest(url: URL)
        self.webView?.load(request)
        
        progressView.trackTintColor = .clear
        progressView.tintColor = DBHexColor("0485d1")
        progressView.frame = CGRect(x: 0, y: 0, width: view.size.width, height: 3.0)
        self.webView?.addSubview(progressView)
        
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        
        if message.name == DBSereneMeadow {
            
        } else if message.name == DBSwilightHour {
            guard let url = message.body as? String else {
                return
            }
            
            if url.hasPrefix("http") || url.hasPrefix("https") {
                self.url = url
            } else {
                DBURLRoute.checkUrl(url: url, replaceTop: true, toNativeFromVC: self, animation: true)
            }
            
        } else if message.name == DBUrbanVibes {
            DBNavigator.currentNavigationController()?.popViewController(animated: true)
        } else if message.name == DBVelvetNight {
            DBNavigator.currentNavigationController()?.popToRootViewController(animated: true)
            DBNavigator.currentNavigationController()?.tabBarController?.selectedIndex = 0
        } else if message.name == DBWhisperWind {
            guard let str = message.body as? String else { return }
            let url = "mailto:" + str
            guard let path = url.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed) else { return }
            guard let URL = URL(string: path) else { return }
            UIApplication.shared.open(URL)
            
        } else if message.name == DBAzureHorizon {
            SKStoreReviewController.requestReview()
        }
    }
    

    
    func updateProgress(progress: Float) {
        self.progressView.alpha = 1
        if progress > self.lastProgress {
            self.progressView.setProgress(Float(self.webView?.estimatedProgress ?? 0) , animated: true)
        } else {
            self.progressView.progress = Float(self.webView?.estimatedProgress ?? 0)
        }
        
        self.lastProgress = progress
        
        if progress >= 1 {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: { [weak self] in
                
                guard let self = self else { return }
                self.progressView.alpha = 0
                self.progressView.progress = 0
                self.lastProgress = 0
            })
        }
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        self.title = webView.title
        self.updateProgress(progress: Float(webView.estimatedProgress))
    }
    

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        
        if webView != self.webView {
            decisionHandler(WKNavigationActionPolicy.allow)
            return
        }
        
        if navigationAction.targetFrame == nil {
            webView.load(navigationAction.request)
        }
        
        decisionHandler(.allow)
    }
    
    override func back() {
        guard let webView = self.webView else { return }
        if webView.canGoBack {
            webView.goBack()
        } else {
            super.back()
        }
    }

}


